#include <iostream>
#include <memory>
#include <vector>
#include <unordered_map>
#include <functional>
#include <unistd.h>

// 定时任务类
using TaskFunc = std::function<void()>;
using ReleaseFunc = std::function<void()>;
class TimerTask
{
private:
    uint64_t _task_id;    // 任务id  用于标识任务，让任务可以被找到
    uint32_t _timeout;    // 定时任务的超时时间
    TaskFunc _task_cb;    // 定时器对象要执行的定时任务
    ReleaseFunc _release; // 用于删除timeWheel中保存的任务对象的信息（删除_timers内部信息）
    bool _canceled;       // 任务是否被取消

public:
    TimerTask(uint64_t id, uint32_t timeout, const TaskFunc &task_cb, ReleaseFunc release_cb)
        : _task_id(id), _timeout(timeout), _task_cb(task_cb), _release(release_cb), _canceled(false) {}
    ~TimerTask()
    {
        if (_canceled == false)
        {
            _task_cb();
            _release();
        }
    }
    uint32_t GetTimeout() { return _timeout; }
    void Cancel() { _canceled = true; } // 取消该任务
};

// 时间轮类
class TimerWheel
{
private:
    using WeakTask = std::weak_ptr<TimerTask>;
    using SharedTask = std::shared_ptr<TimerTask>;

    int _tick;     // 秒针
    int _capacity; // 最大延迟时间
    std::vector<std::vector<SharedTask>> _wheel;
    std::unordered_map<uint64_t, WeakTask> _timers;

private:
    void RemoveTimerMap(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it != _timers.end())
            _timers.erase(id);
    }

public:
    TimerWheel() : _tick(0), _capacity(60), _wheel(_capacity) {}
    // 添加定时任务
    void TimerAdd(uint64_t id, uint32_t timeout, const TaskFunc &cb)
    {
        SharedTask pt(new TimerTask(id, timeout, cb, std::bind(&TimerWheel::RemoveTimerMap, this, id)));
        int pos = (_tick + timeout) % _capacity;
        _wheel[pos].push_back(pt);
        _timers[id] = WeakTask(pt);
    }
    // 延迟定时任务
    void TimerRefresh(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it == _timers.end()) return;
        SharedTask pt = it->second.lock(); // lock获取weak_ptr管理的对象对应的share_ptr

        uint32_t timrout = pt->GetTimeout();
        int pos = (_tick + timrout) % _capacity;
        _wheel[pos].push_back(pt);
    }
    // 秒针向后走一步
    void RunTimerTask() { _tick = (_tick + 1) % _capacity; _wheel[_tick].clear(); }
    // 取消定时任务
    void TimerCancel(uint64_t id)
    {
        auto it = _timers.find(id);
        if (it == _timers.end()) return;
        SharedTask pt= it->second.lock();
        pt->Cancel();
    }
};

class Test
{
public:
    Test() { std::cout << "构造" << std::endl; }
    ~Test() { std::cout << "析构" << std::endl; }
};

void DelTest(Test *t)
{
    delete t;
}

int main()
{
    TimerWheel tw;
    Test *t = new Test();
    tw.TimerAdd(100, 2, std::bind(DelTest, t));

    for (int i = 0; i < 5; i++)
    {
        tw.RunTimerTask();
        tw.TimerRefresh(100);
        std::cout << "刷新了一下定时任务, 重新需要2s后才会销毁" << std::endl;
        sleep(1);
    }
    while (1)
    {
        sleep(1);
        std::cout << "1秒过去了" << std::endl;
        tw.RunTimerTask();
    }
    return 0;
}